/**
exec是正则的方法,而match是string的方法

exec与全局是否定义(/g)无关系,
无论怎样都最多只匹配一个,
但如果定义全局,reg.lastIndex不会自动清零
如果不是全局,reg.lastIndex会清零

而match则与全局相关联,
当定义全局时,match将返回所有匹配到的项,
当不是全局时,只会返回一个
但无论怎样match都会将正则的lastIndex清零
*/

/*const reg = /ab/g;
const text = 'ab c ab defg ab e';
console.log(reg.exec(text));   //[ 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //2
console.log(reg.exec(text)); //[ 'ab', index: 5, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //7
console.log(reg.exec(text)); //[ 'ab', index: 13, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //15
console.log(reg.exec(text)); //null
console.log(reg.lastIndex); //0*/

/** 全局匹配下的match
 * , 结果不带index、input、groups等字段
 * , 只会返回被匹配项的信息*/
/*const reg = /ab/g;
const text = 'ab c ab defg ab e';
console.log(text.match(reg)); //[ 'ab', 'ab', 'ab' ]
console.log(reg.lastIndex); //0
console.log(text.match(reg)); //[ 'ab', 'ab', 'ab' ]
console.log(reg.lastIndex); //0*/

/** 非全局匹配下的match，
 * 返回结果的第一项是被匹配到的字符串（匹配上的部分, 不是原本字符串）
 * 第二项开始(如果有分组的话) 是被匹配上的分组*/
const reg = /ab/;
const text = 'ab c ab defg ab e';
console.log(text.match(reg)); //[ 0: 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]
// console.log(Object.prototype.toString.call(text.match(reg))); //[object Array]
// console.log(text.match(reg).index); //0
// console.log(text.match(reg).input); //ab c ab defg ab e
// console.log(text.match(reg).groups); //undefined
console.log(reg.lastIndex); //0
console.log(text.match(reg)); //[ 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //0

//
/*const reg = /ab/;
const text = 'ab c ab defg ab e';
console.log(reg.exec(text));   //[ 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //0 //即 match不论 是不是全局 都会清零
console.log(reg.exec(text));   //[ 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]
console.log(reg.lastIndex); //0
console.log(text.match(reg)); //[ 'ab', index: 0, input: 'ab c ab defg ab e', groups: undefined ]*/


/*
如果string中有多个与正则匹配的值,
那么第一个exec匹配string中匹配的第一个值,
第二个相同的正则.exec将会选取第二个匹配的值

exec能【步进】匹配（保留当前的reg.lastIndex） 而match最多只能全局匹配(参看上面的例子 text.match(reg)使用全局匹配正则 返回的长这样[ 'ab', 'ab', 'ab' ])

exec最大的优势在于 可以通过match.index(匹配到时的起始位置)和步进模式 拿到非匹配指定的内容（当然text.match(非全局匹配reg) 也能拿到,不过需要每次读一点,就删一点读到的内容,然后再重复读）

比如
*/

/*
const reg = /ab/g;
const text = 'ab c ab defg ab e';
let match;
let lastIndex = reg.lastIndex = 0;
const tmp = [];

while (match = reg.exec(text)) {
  console.log('match:', match);
  console.log('reg.lastIndex:', reg.lastIndex); //2 //7 //15
  if(match.index>lastIndex) { // 说明两次命中之间有非匹配内容, 也把这部分的内容放到tmp里
    tmp.push(text.slice(lastIndex, match.index));
  }
  tmp.push(match[0]);
  lastIndex = match.index + match[0].length;
}

/!** 需要注意的是即使是exec,当匹配完最后一个,也会将reg.lastIndex自动置为0 *!/
console.log('final reg.lastIndex', reg.lastIndex);  // 0
console.log('final lastIndex', lastIndex); // 15
console.log('text.length:',text.length); // 17
/!** 另外这里最后一次reg.exe返回为null 是进不到while的循环体内的
 * 故这里↓ 需要判断一下, 然后把剩余的字符推到tmp里*!/
if (lastIndex < text.length) {
  tmp.push(text.slice(lastIndex));
}
console.log('tmp:',tmp); // tmp: [ 'ab', ' c ', 'ab', ' defg ', 'ab', ' e' ]
*/


/*const reg = /ab/g;
const text = 'ab c ab defg ab e';
console.log(reg.test(text)); //true
console.log(reg.lastIndex); //2
console.log(reg.test(text)); //true
console.log(reg.lastIndex); //7
console.log(reg.test(text)); //true
console.log(reg.lastIndex); //15
console.log(reg.test(text)); //false
console.log(reg.lastIndex); //0*/

/*
const reg = /ab/g;
const text = 'ab c ab defg ab e';
console.log(reg.exec(text)); //true
console.log(reg.lastIndex); //2
console.log(reg.exec(text)); //true
console.log(reg.lastIndex); //7
console.log(reg.exec(text)); //true
console.log(reg.lastIndex); //15
console.log(reg.exec(text)); //null
console.log(reg.lastIndex); //0
*/
